home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Satanic Rites 3
/
Satanic Rites - Issue 3 (1992-11-24)(Destiny).adf
/
coders
/
coders
Wrap
Text File
|
1990-01-05
|
14KB
|
349 lines
{c +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
{c +++++ {e Terminator's coding section. {c+++++
{c +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
{aThis time, I've dedicated the section to the more advanced amongst you.
I'm going to be talking about optimizations, fast tricks and more!
The following optimizations, ideas, routines have come from many sources such
as disk magazines, hearsay, text files, experimentation etc.
First some tricks from a text file found written by Turboslug/Digital
It looked like it was originally intended for publication in Stolen Data
anyway BUT seeing as they decided not to use this, we will!
Destiny got there first!
A quick note to {eTurboslug/Digital{a
Hi Jamie,
Hope you dont mind us using this text but it seems such a waste of
your time and ideas. Also I hope you dont mind that I've corrected spelling
mistakes and reworded various paragraphs!
All the best m8.
Terminator.
Without further ado.... Take it away Jamie!
{c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
{c+++++ {e FASTER BOBS! {c+++++
{c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
{a You need not leave that annoying 16 pixel gap to the right of your bobs!
This can be done by giving the BOB and BOB mask modulo a value of -2.
This means that when the blitter overshoots by 16 pixels and onto the
next line, the blitter module moves it back, and into the correct
position for the next line!
The blitter channels MUST be used in this particular order.
A=Mask, B=Object and C=Screen this means that you can mask out all of
the overshoot rubbish by using blitter channel A, last word mask and
masking out all 16 pixels.
The masking of the mask in turn masks out the rubbish on the BOB!
This saves an inconvenience rather than raster time
{c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
{c+++++{e VERTICAL BLITTER FILL! {c+++++
{c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
{a Vertical, one pass, blitter fill! The blitter has built into it a
horizontal filler, this can be activated by seting one of the bits
in DMACON. However sometimes you may want to do a vertical blitter
fill, to fill in an equalizer, cheat with a big sine scroller etc.
This can be done, again with the blitter by simulating the horizontal
fill except vertically. The blitter channels would be as follows.
A=Oldline, B=Line to fill where the minterms are as follows
00=0, 01=1, 10=1, 11=0 (logical EOR).
This could be done quite slowly, line by line with the blitter,
but using a blitter flaw the process can wrap in on it's self!
The flaw is that when the blitter copies downwards it overwrites
the memory it is copying.
Descending mode would usually be activated when this happens, but we
want it to reuse data from the previous line, so leave it in ascending
mode and the blitter will do a one pass vertical fill!
Blitter channel A starts by pointing to the first line of the area to
fill, and B the second.
{c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
{c+++++{e AUTOMATIC PC RELATIVITY {c +++++
{c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
{a Here we go with Termy's theory of automatic relativity ...
When using OPT A+ in DevPac, automatic PC relative mode addressing
an extension .L must be added to any reference which should remain
absolute. This means that
{fLEA.L $DFF000,A5 ; creates an error!
LEA.L $DFF000.L,A5 ; doesn't!
{a
Use PC relative addressing because it makes your code faster and
totally relocatable. Also it makes it two bytes shorter for every
occurrence of (pc) in your source.
Another trick with PC relativity that most coders forget about is
to make all their jumps relative.
I.e.
{f OLD NEW
Jsr MT_Init Jsr MT_Init(PC)
{a This will also save you two bytes and also makes it relative to the
Program counter.
{c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
{c+++++{e QUICK FORM! {c+++++
{c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
{a I'm still seeing source codes with lame instructions such as...
Clr.l d0 Dont be Lame! Use the faster psuedoops such as
Moveq.l #0,d0.
clr.l d0 uses 6 cycles whereas moveq.l #0,d0 uses 4.
{a Some people say you should only use clr when you wish to preserve
the upper word of a longword
i.e. assume d0 contains 12345678
{fswap d0 {e ; make upper word lower and vice versa
; d0 is now 56781234
{fclr.w d0 {e ; clear lower word
; d0 is now 56780000
{fswap d0 {e ; swap back to normal.
{f d0 will now contain 00005678.
The upper word has now been cleared.
The 3 instructions above took up 6 bytes of code.
Using the same amount of bytes, you can save 4 cycles.
{f And.l #$0000ffff,d0
{a That's it. 16 cycles in the first example and 12 in the second.
{a A lot of coders forget about the Quick forms of addressing.
Some assemblers will tell you (e.g. DevPac)
{e Slow Fast!
{f Move.w #1,d0 Moveq #1,d0
Add.w #1,d0 Addq.w #1,d0
Sub.w #1,d0 Subq.w #1,d0
Add.w #1,a0 Addq.w #1,a0
Sub.w #1,a0 Subq.w #1,a0
{a As you may know, you cant moveq on an address register.
however, Move.w #0,a0 is automatically sign extended by the CPU
which uses 8 cycles. A faster way of clearing an address register
if you have a clear address register spare (E.g. a6) is to ...
{f Move.l a6,Ax ; 4 cycles
{c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
{c+++++{e SHORT WORD ADDRESSING! {c+++++
{c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
{aWhen referring to absolute addresses such as execbase,error vectors etc.
{cDon't use
{f Move.l 4,a6
{aUse short word addressing to your advantage! Use ...
{f Move.l 4.w,a6
{aSimpler and shorter!
{c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
{c+++++{e SPEED UP STATUS REGISTER ACCESS! {c+++++
{c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
{a Another way of slowing down the processor is when checking the
status register. Although most coders very rarely use this,
here are the optimizations...
{e
Slow Whoosh! Effect
{f Ori.b #$4,ccr Moveq #0,d0 = Set 0 flag
Andi.b #$ff-$04,ccr Moveq #1,d0 = Clear 0 flag
Ori.b #$8,ccr Moveq #-1,d0 = Set negative flag
{c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
{c++++{e FAST ANDING AND ORING! {c+++++
{c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
{e Slow! Fast!
{f Move.w d0,d1 ; 4 cycles Moveq #64,d1 ; 4 cycles
And.w #64,d1 ; 8 cycles And.w d0,d1 ; 4 cycles
{f Move.w d6,d7 Moveq #4,d7
Or.w #4,d7 ; 12 cycles Or.w d6,d7 ; 8 cycles!
{a both do exactly the same but the second is 4 cycles faster! Amazing eh?
Just simply faster addressing modes!
{c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
{c+++++{e FAST MULTIPLICATION AND DIVISION! {c+++++
{c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
{a Many coders know how slow the mulu/muls instructions can be.
There are however several fast "cheats" to speed things up a bit.
one way, is if the number you are multiplying by is a power of 2
such as 2,4,8,16 etc. then use a left shift.
{e Slow! Fast!
{f Mulu #4,d0 Lsl.l #2,d0
{a You can also speed up the divs / divu commands by shifting the
opposite directions.
However if the number of shift is less than 3 then its quicker to
use multiple additions.
{e Slow Fast! Faster!
{f Mulu #4,d0 Lsl.l #2,d0 Add.l d0,d0
Add.l d0,d0
{c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
{c+++++{e FAST BIT OPERATIONS ON REGISTERS! {c+++++
{c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
{f Bset #2,d0 Or.w #4,d0 ; 12 > 8
(2x speed increase if or.w Dx1,Dx2)
Bchg #2,d0 Eor.w #4,d0 ; 12 > 8
Bclr #2,d0 And.w #4,d0 ; 12 > 8
{c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
{c+++++{e E.C.S. 60Hz {c +++++
{c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
{a
Okay! I think that's enough optimizations to keep you happy for a while!
Now for some simple things which I think you SHOULD know.
I'm still seeing Lame ECS60Hz programs which fail to work properly even on a
Fatter agnus with 1mb.
The correct ways (As far as I am concerned) are as follows...
{f Move.w #0,$dff1dc ; Turn on ECS 60Hz
Move.w #32,$dff1dc ; Turn off ECS 60Hz
{a
Note! This still won't work on most Tv's!
I've never seen any ECS emulator / activator work on my TV anyway!
Maybe I'm lacking an RGB signal which a monitor gives out or something!
{c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
{c+++++ {e Checking for E.c.s. presence. {c+++++
{c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
{a
I reckon its probably best to check if the computer the program is running
on has the ECS present.
The following routine returns 2 codes in d0 and d1 reporting what ECS chips
are present. The code represents....
{ed0 -
{a $0000 {f = Standard Pal Agnus{a
$1000 {f = Standard NTSC Agnus{a
$2000 {f = ECS Pal Agnus{a
$3000 {f = ECS Ntsc Agnus{a
{ed1 -
{c 0 {f = {e Standard Denise
{c 1 {f = {e ECS Denise
{aThe routine:
{f Lea $dff000,a5
; Get agnus
Move.w 4(a5),d0
And.w #$7f00,d0
; Get Denise
Move.w $f8(a5),d1
And.w #$00ff,d1
Cmp.w #$00fc,d1
Bne.s standard
Moveq.l #1,d1
Rts
standard
Moveq.l #0,d1
Rts
{c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
{c+++++ {e Software rebooting. {c+++++
{c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
{aIs there a 100% official way of hard resetting ?
{aHere are several versions that I know of ....
{f move.w #$4000,$dff09a
Move.l #Rebootcode,$b4
Trap #13
Rebootcode
move.w #0,SR
Jmp $fc0000
{aVersion 2 ....
{f move.l 4.w,a6
lea $fc00d0,a5
jmp -$1e(a6)
{aVersion 3 .... {c(This version was in a commodore text file I)
{f
move.l 4.w,a6
lea reboot(pc),a5
jsr _LVOsupervisor(a6)
cnop 0,4
Reboot
lea.l magic_romend,a0
sub.l magic_sizeoffset(a0),a0
move.l 4(a0),a0
subq.l #2,a0
reset
jmp (a0)
{aWhat a load of shite eh ? None of them actually HARD reboot!
the only way I know of hard rebooting, (And this is the way most viruskillers
do it) is to clear all reset vectors and romtags before soft rebooting using
one of the above routines.
{aAnyone know different ?
{c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
{c+++++ {e THE END IS NIGH ! {c+++++
{c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
{aWell that's about it for this issue, But if you have any ideas,problems
articles or anything else coding related, please write direct to the following
address:{f Dave - Terminator
40,Heol Edward Lewis
Gelligaer
Hengoed
Mid Glamorgan
Cf8 8ej
South Wales
{aOr send an {eE-Mail {amessage on EIS.
{fSee you next time !
{c+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++